import 'package:finance_app/generated/json/base/json_convert_content.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/product_entity.dart';
import 'package:finance_app/src/entities/services_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';

class ServiceAndProductEntity with JsonConvert<ServiceAndProductEntity> {
  ServicesEntity services;
  ProductEntity product;
  int number;

  String get name => services?.name ?? product?.name;

  String get type =>
      product != null && product.id != null ? 'product' : 'service';

  SettingDataTax get tax => services?.tax ?? product?.tax;

  int get id => product?.id ?? services?.id;

  num get amount => services?.price ?? product?.price ?? 0;

  num get totalAmount => number * amount;

  num get discountedAmount {
    num amountAfterDiscounted = isDiscountByPercent
        ? (totalAmount -
                (isInclusive
                    ? totalAmount -
                        (totalAmount / (1 + tax.rate / 100 ?? 0)).toDouble()
                    : 0)) *
            ((100 - discountValue) / 100)
        : (totalAmount -
                (isInclusive
                    ? totalAmount -
                        (totalAmount / (1 + tax.rate / 100 ?? 0)).toDouble()
                    : 0)) -
            discountValue;
    if (isInclusive) {
      return amountAfterDiscounted * (1 + tax.rate / 100);
    } else {
      return amountAfterDiscounted;
    }
  }

  num get discountValue =>
      product?.discountValue ?? services?.discountValue ?? 0;

  String get discountType => services?.discountType ?? product?.discountType;

  bool get isDiscountByPercent => discountType == 'percentage';

  double get taxAmount => isInclusive
      ? discountedAmount -
          (discountedAmount / (1 + tax.rate / 100 ?? 0)).toDouble()
      : discountedAmount * tax.rate / 100;

  int get rate => tax?.rate ?? 0;

  String get key => tax?.key;

  num get price => product?.price ?? services?.price;

  bool get isInclusive {
    if (services?.id != null) {
      return services.isTaxInclusive == 1;
    } else if (product?.id != null) {
      return product.isTaxInclusive == 1;
    }
    return false;
  }

  String get displayDiscountAmount =>
      '${(discountValue != null && discountValue != 0) ? '(${S.current.discount_} ${discountValue.toStringAsFixed(2)}${isDiscountByPercent ? '%' : ''})' : ''}';

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ServiceAndProductEntity &&
          runtimeType == other.runtimeType &&
          services == other.services &&
          product == other.product &&
          number == other.number &&
          name == other.name &&
          tax == other.tax &&
          id == other.id &&
          amount == other.amount &&
          totalAmount == other.totalAmount &&
          taxAmount == other.taxAmount &&
          rate == other.rate &&
          key == other.key &&
          price == other.price &&
          isInclusive == other.isInclusive;

  @override
  int get hashCode =>
      services.hashCode ^
      product.hashCode ^
      number.hashCode ^
      name.hashCode ^
      tax.hashCode ^
      id.hashCode ^
      amount.hashCode ^
      totalAmount.hashCode ^
      taxAmount.hashCode ^
      rate.hashCode ^
      key.hashCode ^
      price.hashCode ^
      isInclusive.hashCode;
}
